#ifndef KAEP_KAEV1_DIGEST_H
#define KAEP_KAEV1_DIGEST_H

#include <bsl_params.h>
#include <crypt_algid.h>
#include <crypt_eal_md.h>

#include "kaev1_memory.h"
#include <wd.h>
#include <wd_digest.h>

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

extern KaeQueuePoolHead *gDigestsNodePool;

#define SM3_BLOCK_NUM   4
#define SM3_DIGEST_SIZE 32

#define MD5_BLOCK_NUM   4
#define MD5_DIGEST_SIZE 16

#define SHA1_BLOCK_NUM   4
#define SHA1_DIGEST_SIZE 20

#define SHA256_BLOCK_NUM   4
#define SHA256_DIGEST_SIZE 32

#define SHA224_BLOCK_NUM   4
#define SHA224_DIGEST_SIZE 28

#define SHA384_BLOCK_NUM   8
#define SHA384_DIGEST_SIZE 48

#define SHA512_BLOCK_NUM   8
#define SHA512_DIGEST_SIZE 64

#define SHA512_224_BLOCK_NUM   8
#define SHA512_224_DIGEST_SIZE 28

#define SHA512_256_BLOCK_NUM   8
#define SHA512_256_DIGEST_SIZE 32

#define DIGEST_BLOCK_SIZE (512 * 1024)
#define DIGEST_CACHE_SIZE (512 * 1024)

#define KAE_REQ

typedef struct KAE_DIGEST_Ctx {
    struct wd_queue *queue;
    struct wd_queue_mempool *pool;
    struct wcrypto_digest_ctx_setup setup;
    struct wcrypto_digest_op_data opData;
    KaeQueueDataEntry *entry;
    CRYPT_MD_AlgId id;
    uint8_t block[DIGEST_CACHE_SIZE];
    void *digestCtx;
    uint32_t digestSize;
    uint32_t remain;
    size_t updatedCount;
} KAE_DIGEST_Ctx;

int WdDigestsInitQnodePool(void);

int WdDigestsDestroyQnodePool(void);

KAE_DIGEST_Ctx *KAE_DIGEST_NewCtx(CRYPT_MD_AlgId md_alg);

int32_t KAE_DIGEST_Init(KAE_DIGEST_Ctx *ctx, BSL_Param *param);

int32_t KAE_DIGEST_Update(KAE_DIGEST_Ctx *ctx, const uint8_t *in, uint32_t len);

int32_t KAE_DIGEST_Final(KAE_DIGEST_Ctx *ctx, uint8_t *out, uint32_t *len);

int32_t KAE_DIGEST_Deinit(KAE_DIGEST_Ctx *ctx);

KAE_DIGEST_Ctx *KAE_DIGEST_Dup(const KAE_DIGEST_Ctx *src);

void KAE_DIGEST_Free(KAE_DIGEST_Ctx *ctx);

#ifdef __cplusplus
}
#endif

#endif /* KAEP_KAEV1_DIGEST_H */